package mrpanyu.guitool.textfile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import mrpanyu.guitool.base.annotation.Action;
import mrpanyu.guitool.base.annotation.OnParameterChange;
import mrpanyu.guitool.base.annotation.Parameter;
import mrpanyu.guitool.base.annotation.ToolModel;
import mrpanyu.guitool.base.model.ParameterType;
import mrpanyu.guitool.base.model.Tool;
import mrpanyu.guitool.base.util.CommonUtils;

@ToolModel(displayName = "根据文件清单提取打包", description = "根据文件清单内容，从目录中提取相关文件并打成zip包")
public class ExtractByFileList {

	@Parameter(displayName = "打包目录", type = ParameterType.DIRECTORY, order = 1)
	private File directory;

	@Parameter(displayName = "文件清单", description = "文本文件(UTF-8)，每行是一个对应打包目录的相对路径", type = ParameterType.FILE, order = 2)
	private File fileList;

	@Parameter(displayName = "处理清单中目录", description = "如果文件清单中某一行为目录，是否提取目录下所有文件", type = ParameterType.SELECT, options = {
			"Y", "N" }, order = 3)
	private String includeDir = "Y";

	@Parameter(displayName = "输出文件", type = ParameterType.FILE, order = 4)
	private File outputFile;

	@OnParameterChange("directory")
	public void onDirectoryChange(Tool tool) {
		if (directory != null || directory.isDirectory()) {
			outputFile = new File(directory, directory.getName() + ".zip");
		}
	}

	@Action(displayName = "提取", order = 1)
	public void extract(Tool tool) throws Exception {
		tool.clearMessages();
		if (directory == null || !directory.isDirectory()) {
			tool.errorMessage("打包目录不存在");
			return;
		}
		if (fileList == null || !fileList.isFile()) {
			tool.errorMessage("文件清单不存在");
			return;
		}
		if (outputFile == null) {
			tool.errorMessage("输出文件不能为空");
		}
		String fileListContent = CommonUtils.readString(fileList, "UTF-8");
		try (FileOutputStream fout = new FileOutputStream(outputFile);
				ZipOutputStream zout = new ZipOutputStream(fout)) {
			List<String> lines = Arrays.asList(fileListContent.split("\n"));
			for (String line : lines) {
				if (CommonUtils.isBlank(line)) {
					continue;
				}
				line = line.trim().replace('\\', '/');
				if (line.startsWith("/")) {
					line = line.substring(1);
				}
				if (line.endsWith("/")) {
					line = line.substring(0, line.length() - 1);
				}
				File file = new File(directory, line);
				if (file.isFile()) {
					addToZip(tool, zout, file);
				} else if (file.isDirectory()) {
					CommonUtils.directoryScan(file, f -> {
						if (f.isFile()) {
							try {
								addToZip(tool, zout, f);
							} catch (Exception e) {
								throw new RuntimeException(e);
							}
						}
					});
				} else {
					tool.errorMessage("文件不存在: " + line);
				}
			}
		}
		tool.infoMessage("已完成提取至文件: " + outputFile);
	}

	private void addToZip(Tool tool, ZipOutputStream zout, File f) throws IOException {
		String path = f.getAbsolutePath();
		path = path.substring(directory.getAbsolutePath().length() + 1).replace('\\', '/');
		zout.putNextEntry(new ZipEntry(path));
		try (FileInputStream fin = new FileInputStream(f)) {
			CommonUtils.copyStream(fin, zout);
		}
		zout.closeEntry();
		tool.infoMessage("添加文件: " + path);
	}

}
